package service

import (
	"context"
	"fmt"
	"go_server/conf"
	"go_server/databases/mongoc"
	"go_server/models/req"
	"go_server/models/res"
	"log"
	"time"

	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
)

func coll() *mongo.Collection {
	return mongoc.MongoClient().Database(conf.ConfigInfo.Mongo.Database).Collection("user")
}
func UserFind(page int64, size int64) ([]*res.User, int64) {
	coll := coll()
	Limit := size
	Skip := (page - 1) * size
	findOpts := &options.FindOptions{
		Limit: &Limit,
		Skip:  &Skip,
	}
	list := make([]*res.User, 0)
	filter := bson.D{{"state", bson.D{{
		"$ne",
		"del",
	}}}}
	cursor, err := coll.Find(context.TODO(), filter, findOpts)
	if err != nil {
		log.Fatal(err)
	}
	for cursor.Next(context.Background()) {
		mb := new(res.User)
		err = cursor.Decode(mb)
		if err != nil {
			return nil, 0
		}
		list = append(list, mb)
	}

	countOpts := options.Count()
	count, err := coll.CountDocuments(
		context.TODO(),
		filter,
		countOpts)
	if err != nil {
		log.Fatal(err)
	}

	return list, count
}
func Login(user *req.UserLoginOrAdd) bool {
	coll := coll()
	opts := options.FindOne().SetSort(bson.D{{"userName", 1}})
	var result bson.M
	err := coll.FindOne(
		context.TODO(),
		bson.D{{"userName", user.UserName}, {"password", user.Password}, {"state", "activity"}},
		opts,
	).Decode(&result)
	if err != nil {
		if err == mongo.ErrNoDocuments {
			return false
		}
		log.Fatal(err)
	}
	return true
}

func UserAdd(user *req.UserLoginOrAdd) bool {
	coll := coll()
	// 判断用户是否以已经存在
	opts := options.FindOne().SetSort(bson.D{{"userName", 1}})
	var result bson.M
	err := coll.FindOne(
		context.TODO(),
		bson.D{{"userName", user.UserName}},
		opts,
	).Decode(&result)

	if err != nil {
		// 账号不存在
		if err == mongo.ErrNoDocuments {
			_, err = coll.InsertOne(context.TODO(), bson.D{
				{"userName", user.UserName},
				{"password", user.Password},
				{"createTime", time.Now()},
				{"state", "activity"},
			})
			if err != nil {
				log.Fatal(err)
			}
			return true
		}
		log.Fatal(err)
	}

	return false
}

func UserSetPassword(data *req.UserSetPassworder) bool {
	coll := coll()
	opts := options.FindOneAndUpdate().SetUpsert(false)
	filter := bson.D{
		{"userName", data.UserName},
		{"password", data.OldPassword},
		{"state", bson.D{{
			"$ne",
			"del",
		}}},
	}
	update := bson.D{{"$set", bson.D{
		{"password", data.NewPassword},
	}}}
	var updatedDocument bson.M
	err := coll.FindOneAndUpdate(context.TODO(), filter, update, opts).Decode(&updatedDocument)

	if err != nil {
		// ErrNoDocuments means that the filter did not match any documents in
		if err == mongo.ErrNoDocuments {
			return false
		}
		log.Fatal(err)
	}
	fmt.Printf("修改后的文档 %v\n", updatedDocument)
	return true
}

func UserDel(user *req.UserLoginOrAdd) bool {
	coll := coll()
	// 判断用户是否以已经存在
	opts := options.FindOne()
	filter := bson.D{{"userName", user.UserName}, {"state", bson.D{{
		"$ne",
		"del",
	}}}}
	var result bson.M
	err := coll.FindOne(
		context.TODO(),
		filter,
		opts,
	).Decode(&result)

	if err != nil {
		// 账号不存在
		if err == mongo.ErrNoDocuments {
			log.Println("账号不存在")
			return false
		}
		log.Fatal(err)
	}

	updataFilter := bson.D{
		{"userName", user.UserName},
		{"password", user.Password},
		{"state", bson.D{{
			"$ne",
			"del",
		}}},
	}
	update := bson.D{{"$set", bson.D{
		{"state", "del"},
	}}}
	updateOpts := options.FindOneAndUpdate().SetUpsert(false)
	var updatedDocument bson.M
	err = coll.FindOneAndUpdate(context.TODO(), updataFilter, update, updateOpts).Decode(&updatedDocument)

	if err != nil {
		if err == mongo.ErrNoDocuments {
			log.Println("密码不正确")
			return false
		}
		log.Fatal(err)
	}
	fmt.Printf("删除后的文档 %v\n", updatedDocument)
	return true
}
